<template>
  <div class="trtc">
    <introduction></introduction>
    <div class="trtc-body">
      <div class="page-left">
        <div class="video-anchor-user">
          <div v-if="isShowUserTrtc">
            <videoBox class="anchor_user_min" v-for="(item, index) in anchorUser" :key="index" :id="item.userId" :userInfo="item" :masterUserId="masterUserId" :isMaster="isMaster" :type="'min'"></videoBox>
          </div>
        </div>
        <div class="whiteboard">
          <TE></TE>
        </div>
        <setBtn @showManagingMembersPopup="showManagingMembersPopup" @screenSharing="screenSharing" @muteVideo="muteVideo" @muteAudio="muteAudio" :isVideo="isVideo" :isAudio="isAudio"></setBtn>
      </div>
      <div class="page-rigth">
        <div v-if="
            roomInfo.status == ROOM_STATUS.conduct ||
            roomInfo.status == ROOM_STATUS.suspend
          " class="video-master-user">
          <videoBox :userInfo="userInfo" :id="userId" :masterUserId="masterUserId" :type="'max'" :isShowUserTrtc="isShowUserTrtc"></videoBox>
        </div>
        <c-tab>
          <IM :trtcRoomId="trtcRoomId" :masterUserId="masterUserId" :isMaster="isMaster" @TRTCControl="TRTCControl"></IM>
        </c-tab>
      </div>
    </div>
    <!-- 屏幕分享 -->
    <screen-sharing v-if="showScreenSharing" @screenSharing="screenSharing"></screen-sharing>
    <!-- 管理人员弹窗 -->
    <managingMembers v-if="showManagingMembers" :lecturerList="lecturerList" :interactionList="interactionList" :audienceList="audienceList" @closeManagingMembersPopup="closeManagingMembersPopup" :type="managingMembersType"></managingMembers>
    <!-- 状态节点弹窗 -->
    <nodeDialog></nodeDialog>
  </div>
</template>

<script>
import TRTC from "trtc-js-sdk";
import videoBox from "./component/videoBox";
import CTab from "./cTab";
import setBtn from "./setBtn";
import TE from "../TE";
import IM from "../IM";
import screenSharing from "./component/screenSharing";
import introduction from "./component/introduction";
import managingMembers from "./component/managingMembers";
import nodeDialog from "./component/nodeDialog"; // IM trtc状态弹窗
import { mapGetters } from "vuex";
import { ROOM_STATUS, USER_TYPE } from "../../../util/constants";
import UserAPI from "@/api/user";
import RoomAPI from "@/api/room";
const sdkAppId = 1400495479;
// 会议室有主持人，讲师，互动观众，这三类都有视频和音频，
export default {
  data() {
    return {
      ROOM_STATUS,
      managingMembersType: 0, //打开管理成员的入口，1从管理成员打开，2导播布局中打开，3点击总人数打开
      showManagingMembers: false,
      masterUserId: "userA", //写死主持人
      masterUserInfo: {
        userId: "userA",
      },
      userId: "", //用户id
      trtcRoomId: null,
      client: null,
      localStream: null,
      userList: [], //所有用户的信息列表,userId用户id同时对应视频标签id，video：是否开启视频，audio：是否开启音频
      // 用户三种类型
      // 1,讲者
      // 2,互动模式(观众可以切换到互动模式)互动模式不等于连麦,连麦需要主持人同意
      // 3,观众模式,观众可以切换到互动模式
      lecturerList: [
        {
          name: "姓名",
          headImg: "头像",
          sysType: "1", //设备系统类型
          onTime: "00:10:30", //在线时长
          isMasterUser: true, //是否是主持人
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "1", //设备系统类型
          onTime: "00:10:30", //在线时长
          isMasterUser: false, //是否是主持人
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: false, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "1", //设备系统类型
          onTime: "00:10:30", //在线时长
          isMasterUser: false, //是否是主持人
          isMasterSpeech: true, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: false, //是否开启视频
          audio: true, //是否开启音频
        },
      ], //讲师列表,包括主持人
      interactionList: [
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 3, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 3, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: true, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 3, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 3, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 3, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 1, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 2, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: true, //是否开启视频
          audio: true, //是否开启音频
        },
      ], //互动模式用户列表
      audienceList: [
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 1, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: false, //是否开启视频
          audio: false, //是否开启音频
        },
        {
          name: "姓名",
          headImg: "头像",
          sysType: "", //设备系统类型
          onTime: "00:10:30", //在线时长
          connectSpeechStatus: 1, //连麦状态,1,未发起连麦,2发起了连麦,3连麦中
          isMasterSpeech: false, //是否是主讲
          weChatName: "微信名",
          work: "主治医师", //工作岗位
          company: "公司", //公司
          video: false, //是否开启视频
          audio: false, //是否开启音频
        },
      ], // 观众列表
      isVideo: false,
      isAudio: true,
      showScreenSharing: false,
    };
  },
  components: {
    videoBox,
    CTab,
    setBtn,
    TE,
    IM,
    screenSharing,
    introduction,
    managingMembers,
    nodeDialog
  },
  computed: {
    // 获取当前会议状态
    ...mapGetters(["TRTCFn", "userInfo", "roomInfo", "TRTCStatus"]),
    userSig() {
      return this.$store.state.userInfo.userSig;
    },
    // 当前用户是否是主持人
    isMaster() {
      return this.masterUserId == this.userId;
    },
    // 获取其他讲师包括互动观众,用于显示视频;
    anchorUser() {
      let anchorUser = JSON.parse(JSON.stringify(this.userList));
      let index = anchorUser.findIndex((item) => {
        return item.userId == this.userId;
      });
      if (index > -1) {
        anchorUser.splice(index, 1);
      }
      return anchorUser;
      // return [{}];
    },
    // 是否显示min视频列表,不显示min时,trtc和白板都不能启动
    // 是否可以观看其他用户音视频(初始化trtc,但不能观看,发布本地流)
    isShowUserTrtc() {
      let status = this.roomInfo.status || false;
      // 如果会议是进行中,或者暂停的
      if (status == ROOM_STATUS.conduct || status == ROOM_STATUS.suspend) {
        // 用户是讲者,主持人,主讲,互动,连麦 显示视频列表
        let userType = this.userInfo.userType; //用户类型
        let isMasterSpeech = this.userInfo.isMasterSpeech; //是否是主讲
        let connectSpeechStatus = this.userInfo.connectSpeechStatus; //连麦状态
        let isInteraction = this.userInfo.isInteraction; //是否是互动
        //..只有用户是观众,且没有连麦,没有互动,没有主讲,才会不显示
        if (
          userType == USER_TYPE.audience &&
          !isMasterSpeech &&
          connectSpeechStatus == 1 &&
          !isInteraction
        ) {
          return false;
        } else {
          return true;
        }
      } else {
        return false;
      }
    },
    // 是否可以创建观看本地流视频
    isCreateStream() {
      // 用户是主持人,讲者,主讲,连麦中,互动 可以观看本地流视频
      let userType = this.userInfo.userType; //用户类型
      let isMasterSpeech = this.userInfo.isMasterSpeech; //是否是主讲
      let connectSpeechStatus = this.userInfo.connectSpeechStatus; //连麦状态
      let isInteraction = this.userInfo.isInteraction; //是否是互动
      if (
        userType == USER_TYPE.lecturer ||
        userType == USER_TYPE.master ||
        isMasterSpeech ||
        connectSpeechStatus == 3 ||
        isInteraction
      ) {
        return true;
      } else {
        return false;
      }
    },
    // 是否可以发布本地视频
    isPublishStream() {
      // 主持人,讲者,主讲,连麦中,可以发布本地流视频
      let userType = this.userInfo.userType; //用户类型
      let isMasterSpeech = this.userInfo.isMasterSpeech; //是否是主讲
      let connectSpeechStatus = this.userInfo.connectSpeechStatus; //连麦状态
      if (
        userType == USER_TYPE.lecturer ||
        userType == USER_TYPE.master ||
        isMasterSpeech ||
        connectSpeechStatus == 3
      ) {
        return true;
      } else {
        return false;
      }
    },
  },
  watch: {
    TRTCFn() {
      // 如果当前方法存在
      if (this[this.TRTCFn.name]) {
        this[this.TRTCFn.name](this.TRTCFn.data);
      }
    },
  },
  async beforeRouteEnter(to, from, next) {
    next((vm) => {
      vm.$store.dispatch("setIMStatus");
      vm.$store.dispatch("setTRTCStatus");
      // vm.$store.dispatch("setUserInfo", to.query);
      // // 更改会议状态
      // vm.$store.dispatch("setRoomStatus", to.query.trtcRoomStatus);
    });
  },
  mounted() {
    this.userId = this.$route.query.userId;
    this.trtcRoomId = this.$route.query.trtcRoomId;
    // 开始会议时,获取前置信息,用户信息-房间信息
    this.getUserAndRoomInfo();
    // 将用户分别放入 讲师数组， 互动用户数组，观众数组
  },
  beforeDestroy() {
    // 退出音视频
    this.leaveRoom();
  },
  methods: {
    // 获取用户和房间信息房间内用户列表
    async getUserAndRoomInfo() {
      let userId = this.userId;
      let res = await Promise.all([
        UserAPI.getUserInfo({ userId }),
        RoomAPI.getRoomInfo({ roomId: this.trtcRoomId }),
        UserAPI.getRoomUserList({ roomId: this.trtcRoomId }),
      ]);
      console.log("获取用户信息和房间信息成功", res);
      if (res && res.length > 0) {
        if (
          res[0].status == 200 &&
          res[1].status == 200 &&
          res[2].status == 200
        ) {
          let userInfo = res[0].data;
          let roomInfo = res[1].data;
          this.userList = res[2].data;
          this.$store.dispatch("setUserInfo", userInfo);
          // 用户获取完信息开启IM功能
          this.$store.dispatch("setIMFn", {
            name: "initTim",
            data: null,
          });
          // 更改房间会议信息
          this.$store.dispatch("setRoomInfo", roomInfo);
          // 如果会议是进行中
          if (roomInfo.status == ROOM_STATUS.conduct) {
            this.init();
          }
        }
      }
    },
    // IM回调的会议房间控制
    IMroomControl(info) {
      console.log("会议房间控制", info);
      if (!info) return;
      if (info.description == "tempo") {
        // 是房间开启 暂停 停止的控制信息
        if (!info.data) return;
        let data = JSON.parse(info.data);
        // 未开始
        if (data.status == ROOM_STATUS.not_started) {
        }
        // 进行中，需要开启白板，开启trtc
        if (data.status == ROOM_STATUS.conduct) {
          // 更改会议状态
          let roomInfo = JSON.parse(JSON.stringify(this.roomInfo));
          roomInfo.status = ROOM_STATUS.conduct;
          this.$store.dispatch("setRoomInfo", roomInfo);
          this.init();
        }
        // 暂停
        if (data.status == ROOM_STATUS.suspend) {
        }
        // 已结束
        if (data.status == ROOM_STATUS.over) {
        }
      }
    },
    // 显示管理成员的弹窗
    showManagingMembersPopup(value) {
      this.managingMembersType = value;
      this.showManagingMembers = true;
    },
    // 关闭管理成员的弹窗
    closeManagingMembersPopup() {
      this.showManagingMembers = false;
    },
    // 点击开启/结束屏幕分享
    screenSharing() {
      this.showScreenSharing = !this.showScreenSharing;
      console.log(this.showScreenSharing);
    },
    // 控制处理数据
    TRTCControl(data) {
      console.log("已经传输至trtc页面", data);
      if (data && data.content && data.content.data) {
        let info = JSON.parse(data.content.data);
        if (info && info.userId) {
          let userId = info.userId;
          let description = data.content.description;
          let has = info.has;
          // 是当前的用户
          if (userId == this.userId && this.localStream) {
            if (description == "video") {
              if (has == "-1") {
                // 关闭视频
                this.localStream.muteVideo();
                this.isVideo = true;
              }
              if (has == "1") {
                // 开启视频
                this.localStream.unmuteVideo();
                this.isVideo = false;
              }
            }
            if (description == "audio") {
              if (has == "-1") {
                // 静音
                this.localStream.muteAudio();
                this.isAudio = false;
              }
              if (has == "1") {
                // 开启声音
                this.localStream.unmuteAudio();
                this.isAudio = true;
              }
            }
            // 发起连麦用户同意之后的操作,开启推流
            if (description == "agreeConnectAudio") {
              this.$store.dispatch("setUserInfo", info);
              this.publishStream(this.localStream);
              // 向其他用户广播新的用户信息
              let data = {
                data: info,
                description: "updateUser",
                extension: "TRTCControl",
              };
              data.data = JSON.stringify(data.data);
              // 向其他用户广播最新用户信息
              this.$store.dispatch("setIMFn", { name: "createCustomMessage", data: { data } });
            }
            // 用户状态改为主讲后的操作
            if (description == 'agreeMasterSpeech') {
              this.$store.dispatch("setUserInfo", info);
              // 向其他用户广播新的用户信息
              let data = {
                data: info,
                description: "updateUser",
                extension: "TRTCControl",
              };
              data.data = JSON.stringify(data.data);
              // 向其他用户广播最新用户信息
              this.$store.dispatch("setIMFn", { name: "createCustomMessage", data: { data } });
            }
          }
          // 添加/修改用户信息
          if (description == "updateUser") {
            console.log("添加/修改用户");
            let index = this.userList.findIndex((item) => {
              return item.userId == userId;
            });
            if (index > -1) {
              this.userList[index] = info;
            } else {
              this.userList.push(info);
            }
          }
          // 删除用户信息
          if (description == "delUser") {
            let index = this.userList.findIndex((item) => {
              return item.userId == userId;
            });
            if (index > -1) {
              this.userList.splice(index, 1);
            }
          }
          // 需要主持人做操作的请求,某人申请连麦,某人申请成为主讲
          if (info.toUserId == this.userId) {
            // 其他用户申请连麦
            if (description == "applyConnectAudio") {

              this.$confirm(`${userId}申请连麦权限，确认是否同意并授予连麦权限`, "申请连麦权限", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
              }).then(res => {
                this.agreeUserConnectAudio(info)
              })
            }
            // 其他用户申请主讲
            if (description == 'applyMasterSpeech') {

              this.$confirm(`${userId}申请主讲权限，确认是否同意并授予主讲权限`, "申请主讲权限", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
              }).then(res => {
                this.agreeUserMasterSpeech(info)
              })
            }
          }
        }
      }
    },
    // 初始化音视频
    init() {
      // 是否初始化音视频
      if (this.isShowUserTrtc) {
        // 开启白板功能
        this.$store.dispatch("setTEFn", { name: "initTE" });
        this.createClient();
      }
    },
    createClient() {

      this.$store.dispatch("setTRTCStatus_initialization", { isShow: true, status: 0 });
      this.client = TRTC.createClient({
        mode: "rtc",
        userId: this.userId,
        sdkAppId: sdkAppId, // 此处填写你的 sdkappid
        userSig: this.userSig,
        // useStringRoomId: true,
      });
      this.$store.dispatch("setTRTCStatus_initialization", { isShow: true, status: 1 });
      setTimeout(() => {
        if ((!this.TRTCStatus[0] || this.TRTCStatus[0].status != 1) && this.TRTCStatus[0].show) {
          this.$store.dispatch("setTRTCStatus_initialization", { isShow: true, status: 4 });
        }
      }, 10000);
      //注册远程监听，要放在加入房间前--这里用了发布订阅模式
      this.subscribeStream();
      // 注册监听退房事件
      this.peerLeave();
      // 进入房间
      this.joinRoom();
      // 监听用户摄像头方法
      this.monitorVideo();
      // 监听用户麦克风方法;
      this.monitorAudio();
    },
    // 获取远端流
    subscribeStream() {
      this.client.on("stream-added", (event) => {
        const remoteStream = event.stream;
        console.log("远端流增加: " + remoteStream.getId());
        console.log("远端流是否包含音频: " + remoteStream.hasAudio());
        console.log("远端流是否包含视频: " + remoteStream.hasVideo());
        let index = this.userList.findIndex((item) => {
          return item.userId == remoteStream.getUserId();
        });
        if (index < 0) {
          this.userList.push({
            userId: remoteStream.getUserId(),
            video: remoteStream.hasVideo(),
            audio: remoteStream.hasAudio(),
          });
        }
        //订阅远端流 取消订阅流unsubscribe
        this.client.subscribe(remoteStream);
      });
    },
    //   进入房间
    joinRoom() {
      this.$store.dispatch("setTRTCStatus_join", { isShow: true, status: 0 });
      setTimeout(() => {
        if ((!this.TRTCStatus[1] || this.TRTCStatus[1].status != 1) && this.TRTCStatus[1].show) {
          this.$store.dispatch("setTRTCStatus_join", { isShow: true, status: 4 });
        }
      }, 10000);

      this.client
        .join({ roomId: this.trtcRoomId - 0 })
        .catch((error) => {
          this.$store.dispatch("setTRTCStatus_join", { isShow: true, status: 2 });
          console.error("进房失败 ", error);
        })
        .then((res) => {
          this.$store.dispatch("setTRTCStatus_join", { isShow: true, status: 1 });
          console.log("进房成功");
          //   播放远程
          this.playStream();
          // 是否创建本地音视频
          if (this.isCreateStream) {
            this.createStream();
          }
        });
    },
    // 重新加入房间
    againJoinRoom() {
      this.client.leave().then(res => {
        this.localStream.stop();
        // 关闭本地流
        this.localStream.close();
        this.joinRoom();
      }).catch(err => {
        this.$store.dispatch("setTRTCStatus_join", { isShow: true, status: 1 });
      });
    },
    //初始化本地音视频流
    createStream() {
      this.$store.dispatch("setTRTCStatus_create", { isShow: true, status: 0 });
      setTimeout(() => {
        if ((!this.TRTCStatus[3] || this.TRTCStatus[3].status != 1) && this.TRTCStatus[3].show) {
          this.$store.dispatch("setTRTCStatus_create", { isShow: true, status: 4 });
        }
      }, 10000);

      // 用户id,是否开启音频,是否开启视频
      const localStream = TRTC.createStream({
        userId: this.userId,
        audio: this.userInfo.audio,
        video: this.userInfo.video,
      });
      this.localStream = localStream;
      localStream
        .initialize()
        .catch((error) => {
          console.error("初始化本地流失败 " + error);
          this.$store.dispatch("setTRTCStatus_create", { isShow: true, status: 2 });
        })
        .then(() => {
          console.log("初始化本地流成功");
          this.$store.dispatch("setTRTCStatus_create", { isShow: true, status: 1 });
          // 创建好后才能播放
          localStream.play(this.userId);
          // 是否发布本地流视频
          if (this.isPublishStream) {
            //创建好后才能发布
            this.publishStream(this.localStream);
          }
        });
    },
    againCreateStream() {
      this.localStream.stop();
      // 关闭本地流
      this.localStream.close();
      // 是否发布本地流视频
      if (this.isPublishStream) {
        this.unpublish();
      }
      this.createStream();
    },
    // 禁用/启用本地音频
    muteAudio(status) {
      if (!this.localStream) return;
      if (!status) {
        this.localStream.muteAudio();
        console.log("静音成功");
      } else {
        this.localStream.unmuteAudio();
        console.log("开启声音成功");
      }
    },
    // 禁用/启用本地音频
    muteVideo(status) {
      if (!this.localStream) return;
      if (status) {
        this.localStream.muteVideo();
      } else {
        console.log('关闭本地视频')
        this.localStream.unmuteVideo();
      }
    },
    //发布本地音视频流
    publishStream() {

      this.$store.dispatch("setTRTCStatus_push", { isShow: true, status: 0 });
      setTimeout(() => {
        if ((!this.TRTCStatus[4] || this.TRTCStatus[4].status != 1) && this.TRTCStatus[4].show) {
          this.$store.dispatch("setTRTCStatus_push", { isShow: true, status: 4 });
        }
      }, 10000);
      if (!this.localStream) return;

      this.client
        .publish(this.localStream)
        .catch((error) => {
          console.error("本地流发布失败 " + error);
          this.$store.dispatch("setTRTCStatus_push", { isShow: true, status: 2 });
        })
        .then(() => {
          // if (this.isMaster) {
          console.log("是主持人,监测混流模式");
          this.$store.dispatch("setTRTCStatus_push", { isShow: true, status: 1 });
          let config = {
            mode: "preset-layout",
            videoWidth: 1280,
            videoHeight: 720,
            videoBitrate: 1500,
            videoFramerate: 15,
            videoGOP: 2,
            audioSampleRate: 48000,
            audioBitrate: 64,
            audioChannels: 1,
            // 预设一路本地摄像头、一路本地屏幕分享、两路远端流的排版位置
            mixUsers: [
              // {
              //   width: 960,
              //   height: 720,
              //   locationX: 0,
              //   locationY: 0,
              //   pureAudio: false,
              //   userId: "share_123456", // 本地屏幕分享占位，填写用于推屏幕分享流的 client userId
              //   zOrder: 1,
              // },
              {
                width: 320,
                height: 240,
                locationX: 960,
                locationY: 0,
                pureAudio: false,
                userId: this.masterUserId, // 本地摄像头占位，填写用于推摄像头流的 client userId
                zOrder: 1,
              },
              {
                width: 320,
                height: 240,
                locationX: 960,
                locationY: 240,
                pureAudio: false,
                userId: "user_5823172", // 远端流占位
                zOrder: 1,
              },
              {
                width: 320,
                height: 240,
                locationX: 960,
                locationY: 480,
                pureAudio: false,
                userId: "user_5823178", // 远端流_白板(服务器端使用白板推流,将其作为音视频流推出,在房间内会受到当前的白板音视频)
                zOrder: 1,
              },
            ],
          };
          // let res = this.client.startMixTranscode(config);
          // res
          //   .then((res) => {
          //     console.log("开启混流成功", res);
          //   })
          //   .catch((err) => {
          //     console.log("开启混流失败", err);
          //   });
          // }
          console.log("本地流发布成功");
        });
    },
    // 取消发布本地流
    unpublish() {
      this.client.unpublish(this.localStream)
    },
    //播放远端流
    playStream() {
      console.log("播放远端流");
      this.client.on("stream-subscribed", (event) => {
        const remoteStream = event.stream;
        console.log("远端流订阅成功：");
        console.log(event);
        // console.log("远端流订阅成功：" + remoteStream.getId());
        // console.log("远端流订阅成功：" + remoteStream.userId_);
        // console.log("获取远端流所属用户id: " + remoteStream.getUserId());
        this.$nextTick(() => {
          remoteStream.play(remoteStream.userId_);
        });
      });
    },
    // 退出音视频
    leaveRoom() {
      // 停止混流
      // this.client.stopMixTranscode();
      if (!this.client) return;
      this.client
        .leave()
        .then(() => {
          console.log("退房成功");
          // 停止本地流，关闭本地流内部的音视频播放器
          this.localStream.stop();
          // 关闭本地流
          this.localStream.close();
          this.localStream = null;
          this.client = null;
          // 退房成功，可再次调用client.join重新进房开启新的通话。
        })
        .catch((error) => {
          // 错误不可恢复，需要刷新页面。
          console.error("退房失败 " + error);
        })
    },
    // 监听其他用户退房
    peerLeave() {
      this.client.on("stream-removed", (event) => {
        const remoteStream = event.stream;
        console.log("其他用户退房1", remoteStream);
        remoteStream.stop();
        // let userId = remoteStream.getUserId();
        // let index = this.userList.findIndex((item) => {
        //   return item.userId == userId;
        // });
        // this.userList.splice(index, 1);
      });
    },
    // 监听其他用户摄像头动作(开启,关闭)
    monitorVideo() {
      this.client.on("mute-video", (event) => {
        console.log("用户关闭了摄像头", event);
        this.setUser(event.userId, "video", false);
      });
      this.client.on("unmute-video", (event) => {
        console.log("用户开启了摄像头", event);
        this.setUser(event.userId, "video", true);
      });
    },
    // 监听其他用户麦克风动作(开启,关闭)
    monitorAudio() {
      this.client.on("mute-audio", (event) => {
        console.log("用户关闭了麦克风", event);
        this.setUser(event.userId, "audio", false);
      });
      this.client.on("unmute-audio", (event) => {
        console.log("用户开启了麦克风", event);
        this.setUser(event.userId, "audio", true);
      });
    },
    // 设置某个用户摄像头,麦克风..
    setUser(userId, type, value) {
      let index = this.userList.findIndex((item) => {
        return item.userId == userId;
      });
      if (index > -1) {
        this.userList[index][type] = value;
      }
      console.log(this.userList[index]);
    },
    // 同意某个用户连麦,向服务器发送消息
    async agreeUserConnectAudio(userInfo) {
      let res = await UserAPI.updateUserInfo({
        userId: userInfo.userId,
        userInfo: { connectSpeechStatus: 3, audio: true },
      });
      if (res && res.status == 200 && res.data.userId) {
        console.log('同意连麦成功', res)
        this.$message({ type: "success", message: "同意连麦成功", });
        // 同意连麦成功后,向发起人发送同意的消息
        let data = {
          data: res.data,
          description: "agreeConnectAudio",
          extension: "TRTCControl",
        };
        data.data = JSON.stringify(data.data);
        this.$store.dispatch("setIMFn", { name: "createCustomMessage", data: { data } });
      } else {
        console.log('同意连麦失败', res)
        this.$message({ type: "error", message: "同意连麦失败", });
      }
    },
    // 同意某个用户申请主讲,向服务器发送消息
    async agreeUserMasterSpeech(userInfo) {
      let res = await UserAPI.updateUserInfo({
        userId: userInfo.userId,
        userInfo: { isMasterSpeech: true, audio: true, video: true },
      });
      if (res && res.status == 200 && res.data.userId) {
        console.log('同意申请主讲成功', res)
        this.$message({ type: "success", message: "设置主讲成功", });
        //设置主讲成功后,向发起人发送同意的消息
        let data = {
          data: res.data,
          description: "agreeMasterSpeech",
          extension: "TRTCControl",
        };
        data.data = JSON.stringify(data.data);
        this.$store.dispatch("setIMFn", { name: "createCustomMessage", data: { data } });
      } else {
        console.log('设置主讲成功', res)
        this.$message({ type: "error", message: "设置主讲失败", });
      }
    }
  },
};
</script>

<style  lang="scss">
.trtc {
  width: 100%;
  height: 100%;
  display: flex;
  overflow: hidden;
  flex-direction: column;
  justify-content: space-between;
  .trtc-body {
    flex: 1;
    display: flex;
    .page-left {
      background: #ececec;
      display: flex;
      flex-direction: column;
      width: 75.55vw;
      .video-anchor-user {
        text-align: left;
        white-space: nowrap;
        overflow-x: auto;
        height: 11.33vh;
        .anchor_user_min {
          white-space: nowrap;
          display: inline-block;
        }
      }
      .whiteboard {
        width: 100%;
        img {
          height: 60vh;
          width: 100%;
        }
      }
      .setting {
        display: flex;
      }
    }
    .page-rigth {
      background: #f5f5f5;
      width: 24.44vw;
      display: flex;
      flex-direction: column;
    }
  }
}
</style>
